
#include <wsnos.h>

static subscrlist g_subscr_sto[OSEL_SUBSCRLIST_NUM];	

subscrlist *osel_subscrlist;
osel_signal_t osel_maxsignal;


osel_uint8_t const CODE osel_map_tbl[64] = 
{
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U,
    0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U
};

osel_uint8_t const CODE osel_div8lkup[64]=
{
    0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U,
    1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U,
    2U, 2U, 2U, 2U, 2U, 2U, 2U, 2U,
    3U, 3U, 3U, 3U, 3U, 3U, 3U, 3U,
    4U, 4U, 4U, 4U, 4U, 4U, 4U, 4U,
    5U, 5U, 5U, 5U, 5U, 5U, 5U, 5U,
    6U, 6U, 6U, 6U, 6U, 6U, 6U, 6U,
    7U, 7U, 7U, 7U, 7U, 7U, 7U, 7U

};


extern task_cb g_task_cb[OSEL_MAX_PRIO];

/************************************************************/
void osel_sub_init(void)
{
	osel_subscrlist = &g_subscr_sto[0];
	osel_maxsignal = OSEL_DIM(g_subscr_sto);
}

void osel_subscribe(task_cb const * const tcb, osel_signal_t sig)
{
    osel_uint8_t prio = tcb->task.prio;
	OSEL_ASSERT(prio < OSEL_MAX_PRIO);
	
	osel_uint8_t i = osel_div8lkup[prio];

	OSEL_INT_LOCK();
	osel_subscrlist[sig].bits[i] |= osel_map_tbl[prio];
	OSEL_INT_UNLOCK();
}

void osel_unsubscribe(task_cb * const tcb, osel_signal_t sig)
{
	event_pool_t *epool = OSEL_NULL;
	osel_uint8_t prio = tcb->task.prio;
	OSEL_ASSERT(prio < OSEL_MAX_PRIO);
	list_head_t *queue_list_head;

	osel_uint8_t i = osel_div8lkup[prio];

	OSEL_INT_LOCK();

	if((osel_subscrlist[sig].bits[i] & osel_map_tbl[prio]) == osel_map_tbl[prio])
	{
		osel_subscrlist[sig].bits[i] &= ~osel_map_tbl[prio];	
		queue_list_head = &(tcb->queue);
		while (queue_list_head->next != &(tcb->queue))
		{
			epool = list_entry(queue_list_head->next, event_pool_t, list);
			if(epool->eblock->type == sig)
			{
				list_del(&epool->list);
				
				if (--(epool->eblock->cnt) == 0)
				{
					osel_eblock_free(&(epool->eblock) __EBLOCK_LINE2);
				}
				osel_epool_free(&epool __EPOOL_LINE2);
			}
			queue_list_head = queue_list_head->next;
		}
	}
	
	OSEL_INT_UNLOCK();
}

/**@}**/
